package cwb1;


import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;

/**
 * This class represents the general transmission from data between the application and the database.
 * 
 * @author Aurora
 *
 */
public class DatabaseCommunicator {
	
	//Google datastoreService
	private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	
	
	//Maximum value of a kind that can be stored in the database.
	private final int INFINITY = Integer.MAX_VALUE;
	
	private static DatabaseCommunicator instance = new DatabaseCommunicator();
	
	private DatabaseCommunicator() {
		
	}
	
	public static DatabaseCommunicator getInstance() {
		return instance;
	}
	
	/**
	 * Puts a entity in the google database.
	 * 
	 * @param entity The entity to be put
	 * @param data The Data which properties must be put in the database with the given entity.
	 */
	public void put(Entity entity, Map<String,Object> properties)
	{
		for(String lusKey : properties.keySet()) {
			entity.setProperty(lusKey, properties.get(lusKey));
		}
		
		datastore.put(entity);
	}
	
	/**
	 * Returns the entity from the database with the given key.
	 * 
	 * @param key The key of the database.
	 * @return The entity with the given key.
	 * @throws EntityNotFoundException When the entity is not found.
	 */
	public Entity get(Key key) throws EntityNotFoundException {
		return datastore.get(key);
	}
	
	/**
	 * Updates an entity with given key and properties from the data.
	 * @param key The key of the entity.
	 * @param data The data which properties must be updated.
	 * @throws EntityNotFoundException When the key is not found.
	 */
	public void update(Key key, Map<String,Object> properties) throws EntityNotFoundException
	{
		put(get(key),properties);
	}
	
	/**
	 * Deletes a entity with given key from the database.
	 * 
	 * @param key The key of the entity that will be deleted.
	 */
	public void delete(Key key)
	{
		datastore.delete(key);
	}
	
	/**
	 * Returns all the entities with given parent key and kind.
	 * 
	 * @param parent The parent key of all the entities.
	 * @param kind The kind of all the entities.
	 * @return a List with all the entities with given king and parent key.
	 */
	public List<Entity> getAll(Key parent, String kind)
	{
		Query query = new Query(kind, parent);
		return datastore.prepare(query).asList(FetchOptions.Builder.withLimit(INFINITY));
	}
}
